精通Linux系列十六:为什么有个进程kill不掉?
精通Linux系列点击关注公众号,AI&编程干货及时送达
控制进程
命令 | 含义 |
kill | 结束一个进程(或向其发送一个信号)。 |
timeout | 杀掉运行过久的命令。 |
nice | 以特定的优先级调用程序。 |
renice | 在进程运行时改变其优先级。 |
flock | 使用锁确保一次只有一个进程的副本在运行。 |
进程开始之后,它们可以被停止,重新启动,杀死和重新优先化。我们在 [“Shell Job Control”] 中讨论了一些由 shell 处理的这些操作。现在我们来讨论杀死和重新优先化。
kill
stdin stdout - file -- opt --help --version
kill [选项] [进程ID]
kill
命令向进程发送信号。这可以结束进程(默认行为),中断它,挂起它,使其崩溃,等等。你必须是进程的所有者,或者是超级用户,才能影响它。例如,要终止进程 13243,运行:
→ kill 13243
如果这不起作用 - 有些程序在不终止的情况下捕获此信号 - 添加 -KILL
或者(等同的)-9
选项:
→ kill -KILL 13243
然而,这对于程序来说并不是一个正常的退出,它可能在死亡时留下分配的资源(或引发其他不一致性)。
如果你不知道进程的 PID,运行 ps
并检查输出:
→ ps -uax | grep emacs
或者更好的是,试试 pidof
命令,它可以根据其名称查找并打印进程的 PID:
→ pidof emacs
8374
现在你可以在一行中只通过程序名杀死进程,使用 shell 反引号来执行 pidof
:
→ kill `pidof emacs`
或者使用 killall
命令杀死给定程序的所有进程:
→ killall emacs
除了文件系统中的 kill
程序(通常是 /bin/kill),大多数 shell 都有内置的 kill
命令,但是它们的语法和行为不同。然而,它们都支持以下用法:
→ kill -N PID
→ kill -NAME PID
其中 N
是信号数字,*NAME
* 是没有前导“SIG”的信号名称(例如,使用 -HUP
发送 SIGHUP
信号)。要查看 kill
发送的所有信号的完整列表,运行 kill -l
,尽管它的输出取决于你正在运行哪个 kill
。要查看信号的描述,运行 man 7 signal
。
timeout
stdin stdout - file -- opt --help --version
timeout [选项] 秒数 命令...
timeout
命令为运行另一个程序设置时间限制,单位为秒。如果程序运行的时间超过限制,timeout
会杀死它。作为示范,这是一个 sleep
命令,它应该运行一分钟,但在 3 秒后被杀死:
→ sleep 60 运行 60 秒
→ timeout 3 sleep 60 在 3 秒后被杀死
作为一个更实际的例子,从你的 MP3 集合中播放一小时的音乐,然后停止:
→ timeout 3600 mplayer *.mp3
有用的选项
-s * 信号* | 发送一个除默认(TERM)之外的信号。选择项与 kill -l 列出的相同。 |
-k * 秒数* | 如果程序在第一次信号后还没有死,等待这么多秒后发送一个致命的 KILL 信号。 |
nice
stdin stdout - file -- opt --help --version
nice [-n 级别] 命令行
在调用系统密集型程序时,你可以通过降低其优先级来对其他进程(和用户)友好。这就是 nice
命令的作用:它为进程设置一个 nice 级别(一定量的“友善度”),以便它在 Linux 进程调度器中得到较少的关注。[17] 这是一个将大任务设置为在 nice 级别 7 运行的例子:
→ nice -n 7 sort hugefile > outfile
如果你运行 nice
但没有指定级别,将使用 10。普通进程(没有使用 nice
运行)在零级别运行,你可以通过运行 nice
并不带任何参数来查看:
→ nice
0
超级用户也可以降低 nice 级别,增加进程的优先级:
→ sudo nice -n -10 myprogram
要查看你的任务的 nice
级别,使用 ps
并查看“NI”列:
→ ps -o pid,user,args,nice
renice
stdin stdout - file -- opt --help --version*
renice [-n N] [选项] PID
nice
命令可以在给定的 nice 级别下调用一个程序,renice
则可以改变一个已经在运行的进程的 nice 级别。这里我们将进程 28734 的 nice
级别增加 5:
→ renice -n 5 -p 28734
作为一个快速(但微不足道)的测试,你可以创建一个仅休眠2分钟的进程,将其在后台运行,并更改其优先级:
→ sleep 120 &
→ pidof sleep
2673
→ renice -n 5 -p 2673
2673 (进程 ID) 旧优先级 0,新优先级 5
普通用户可以提高他们自己进程的 nice 级别,而超级用户还可以降低它(提高优先级)并可以操作任何进程。有效范围是 −20 到 +20,但要避免使用高的负数,否则你可能会干扰到关键的系统进程。
有用的选项
-p pid | 影响给定的进程 ID。你可以省略 -p ,只提供一个 PID(renice -n 5 28734 )。 |
-u username | 影响由给定用户拥有的所有进程。 |
flock
stdin stdout - file -- opt --help --version
flock [options] lockfile command...
你是否需要确保一次只有一个程序的副本在你的计算机上运行?例如,如果你每小时使用 rsync
命令运行自动备份,那么之前的备份可能仍在运行,当下一个备份启动时。flock
命令解决了这种问题。它阻止一个命令(例如备份脚本)与自身并发运行。如果你尝试一次运行该命令的两个副本,第二个将失败。例如,当与 flock
一起运行时,此 rsync
命令将立即失败,如果同一命令的另一个实例已经在运行:
→ flock -n /tmp/mylock rsync ...
要查看 flock
的实际效果,请打开两个 shell 窗口,并在每个 shell 中依次运行以下命令(我们将使用 sleep
命令作为演示,它只是等待给定的秒数):
→ flock -n /tmp/mylock sleep 60
第一个命令将运行,第二个将立即终止。这两个命令不必完全相同,但它们必须引用第一个参数中相同的 *lockfile
*。这可以是任何文件或目录的名称,flock
将其视为一个唯一标记,以防止其他命令的运行。例如,如果你在一个 shell 中运行相同的 sleep
命令,并在另一个中使用相同的锁文件运行不同的命令,比如 ls
:
→ flock -n /tmp/mylock ls
第二个仍将失败。但如果你提供不同的锁文件,两个命令都将运行。
有用的选项
-n | 如果另一个命令已经在运行,立即失败。 |
-w * N* | 如果另一个命令已经在运行,等待 N 秒后失败。 |
-s | 使用共享锁代替独占锁。使用此选项时,你可以同时运行多个命令,但如果省略该选项,flock 将失败。这对允许有限数量的命令同时运行很有用。 |
推荐阅读
你好,我是拾叁,7年开发老司机、互联网两年外企5年。怼得过阿三老美,也被PR comments搞崩溃过。这些年我打过工,创过业,接过私活,也混过upwork。赚过钱也亏过钱。一路过来,给我最深的感受就是不管学什么,一定要不断学习。只要你能坚持下来,就很容易实现弯道超车!所以,不要问我现在干什么是否来得及。如果你还没什么方向,可以先关注我,这里会经常分享一些前沿资讯和编程知识,帮你积累弯道超车的资本。